/*
 * device.cc
 *
 *  Created on: Dec 8, 2010
 *      Author: fify
 */


#include "device.h"
#include <stdlib.h>
#include <sstream>
#include <stdio.h>
using std::istringstream;

namespace CncrVDevice
{

VCmdRoute::VCmdRoute() : VCmd()
{
	m_type = CMD_ROUTE;
}

VCmdInterface::VCmdInterface(VItf *itf) :VCmd()
{
	m_type = CMD_INTERFACE;
	m_itf = itf;
}

u_int32_t VRouter::cmd_count()
{
	return m_cmds.size();
}

VRouter::VRouter()
{
	m_type = DEV_ROUTER;
}

int VRouter::add_cmds(string &cmds)
{
	char line[1024];
	istringstream iss(cmds);

	int ret = 0;
	while(iss.getline(line, 1023) != NULL)
	{
		string cmd = string(line);
		if(cmd.length() > 0)
			ret += add_cmd(cmd);
	}

	return ret;
}

int VRouter::add_cmd(string &line)
{
	FILE *file = fopen("log.txt", "a");
	fprintf(file, "Adding command: %s\n", line.c_str());
	fclose(file);
	istringstream iss(line);

	string cmd_type;

	iss >> cmd_type;

	if(cmd_type.length() <= 0)
		return 0;

	if(cmd_type == "route")
	{
		return add_route_cmd(iss);
	}

	if(cmd_type == "interface")
	{
		return add_interface(iss);
	}
	// TODO: Parse other commands.

	return 0;
}

int VRouter::remove_cmd(int pos)
{
	if(pos >= (int)m_cmds.size())
		return 0;
	m_cmds.erase(m_cmds.begin() + pos);
	return 1;
}

int VRouter::add_route_cmd(istringstream &iss)
{
	/*
	 * Route Command: route ip(xx.xx.xx.xx) mask(int) nitf(n) next_hop(xx.xx.xx.xx).
	 */
	string ip_dest, ip_next_hop;
	unsigned mask, nitf;

	iss >> ip_dest >> mask >> nitf >> ip_next_hop;

	FILE *file = fopen("log.txt", "a");
	fprintf(file, "\n ########################### %s %d %d %s\n", ip_dest.c_str(), mask, nitf, ip_next_hop.c_str());
	fclose(file);
	if(ip_dest.length() == 0 || mask > 32 || mask < 0 || ip_next_hop.length() == 0
			|| ip_next_hop == "0.0.0.0")
		return 0;

	VCmdRoute *cmd = new VCmdRoute();
	if(inet_aton(ip_dest.c_str(), &cmd->m_dest.ip) == 0)	// illegal IP address.
		return 0;

	cmd->m_dest.mask = mask;
	cmd->m_dest.ip.s_addr &= htonl(((int32_t)-1) << (32 - cmd->m_dest.mask));

	if(inet_aton(ip_next_hop.c_str(), &cmd->m_next_hop.ip) == 0)
		return 0;
	//cmd->m_itf = m_itfs[nitf];

	m_cmds.push_back(cmd);

	return 1;
}

int VRouter::add_interface(istringstream &iss)
{
	/*
	 * Interface Command: interface nitf ip(xx.xx.xx.xx) mask(int) mac(xx:xx:xx:xx:xx:xx)
	 */
	string ip_addr, mac_addr;
	unsigned mask, nitf;

	iss >> nitf >> ip_addr >> mask >> mac_addr;

	while(m_itfs.size() < nitf + 1)
			m_itfs.push_back(NULL);

	m_itfs[nitf] = new VEtherItf("", this);

	ip_addr_t addr;
	if(inet_aton(ip_addr.c_str(), &addr.ip) == 0)   // illegal IP address.
			return 0;
	addr.mask = mask;

	((VEtherItf*)m_itfs[nitf])->m_mac = mac_addr;
	((VEtherItf*)m_itfs[nitf])->m_index = nitf;
	((VEtherItf*)m_itfs[nitf])->m_ip.push_back(addr);

	VCmdInterface *cmd = new VCmdInterface(m_itfs[nitf]);
	cmd->m_addrs.push_back(addr);

	m_cmds.push_back(cmd);

	return 1;
}


} // End of namespace.
